import os
import base64
from hashlib import sha256
from hmac import HMAC

SALT_LEN = 8
ENCRYPT_TIME = 10


def encrypt_msg(msg, salt=None):
    """Hash msg on the fly."""
    if salt is None:
        salt = os.urandom(8)  # 64 bits.

    assert SALT_LEN == len(salt)
    assert isinstance(salt, bytes)
    assert isinstance(msg, str)

    if isinstance(msg, str):
        msg = msg.encode("UTF-8")

    assert isinstance(msg, bytes)

    result = msg
    for i in range(ENCRYPT_TIME):
        result = HMAC(result, salt, sha256).digest()

    return salt + result


def validate_msg(hashed, msg):
    return hashed == encrypt_msg(msg, salt=hashed[:SALT_LEN])


def encrypt_pwd(password):
    hashed = encrypt_msg(password)
    return (base64.b64encode(hashed)).decode("UTF-8")


def validate_pwd(encrypt, password):
    hashed = base64.b64decode((encrypt).encode("UTF-8"))
    return validate_msg(hashed, password)


if __name__ == "__main__":
    hashed = encrypt_msg("secret password")
    assert validate_msg(hashed, "secret password")
    print(hashed)
    print(base64.b64encode(hashed))
    print(base64.b64decode(base64.b64encode(hashed)))
    encrypt = encrypt_pwd("secret password")
    print(encrypt)
    assert validate_pwd(encrypt, "secret password")
